मानो या न मानो, एन्क्रिप्टेड डेटा के साथ गणना करना संभव है। दूसरे शब्दों में, ऐसा प्रोग्राम चलाना संभव है जहां प्रोग्राम में सभी चर हैं एन्क्रिप्टेड!
इस ट्यूटोरियल में, हम एन्क्रिप्टेड कम्प्यूटेशन के बहुत ही बुनियादी टूल्स से गुजरने वाले हैं। विशेष रूप से, हम एक लोकप्रिय दृष्टिकोण पर ध्यान केंद्रित करने जा रहे हैं जिसे सिक्योर मल्टी-पार्टी कम्प्यूटेशन कहा जाता है। इस पाठ में, हम सीखेंगे कि एक एन्क्रिप्टेड कैलकुलेटर का निर्माण कैसे करें जो एन्क्रिप्टेड संख्याओं पर गणना कर सकता है।
लेखक:
संदर्भ:
nbTranslate का उपयोग करके अनुवादित
संपादक:
SMPC पहली नज़र में "एन्क्रिप्शन" का एक अजीब रूप है। चर को एन्क्रिप्ट करने के लिए सार्वजनिक / निजी कुंजी का उपयोग करने के बजाय, प्रत्येक मान को कई shares
में विभाजित किया जाता है, जिनमें से प्रत्येक एक निजी कुंजी की तरह काम करता है। आमतौर पर, ये share
2 या अधिक owners के बीच वितरित किए जाएंगे। इस प्रकार, चर को डिक्रिप्ट करने के लिए, सभी owners को डिक्रिप्शन की अनुमति देने के लिए सहमत होना चाहिए। संक्षेप में, सभी के पास एक निजी कुंजी है।
तो, मान लें कि हम एक चर 'x' को "एन्क्रिप्ट" करना चाहते हैं, हम निम्नलिखित तरीके से ऐसा कर सकते हैं।
> एन्क्रिप्शन फ़्लोट्स या वास्तविक संख्याओं का उपयोग नहीं करता है, लेकिन एक गणितीय स्थान में होता है जिसे integer quotient ring कहा जाता है जो मूल रूप से 0
औरQ-1
के बीच पूर्णांक है, जहां Q
प्राइम् और "पर्याप्त" है ताकि हमारे प्रयोगों में उपयोग किए जाने वाले सभी नंबर शामिल हो सकें। व्यवहार में, 'x' पूर्णांक को मान देते हुए, हम रिंग में फिट होने के लिए x % Q
करते हैं। (इसीलिए हम नंबर x' > Q
का उपयोग करने से बचते हैं)।
In [1]:
Q = 1234567891011
In [2]:
x = 25
In [3]:
import random
def encrypt(x):
share_a = random.randint(-Q,Q)
share_b = random.randint(-Q,Q)
share_c = (x - share_a - share_b) % Q
return (share_a, share_b, share_c)
In [4]:
encrypt(x)
Out[4]:
In [5]:
def decrypt(*shares):
return sum(shares) % Q
In [6]:
a,b,c = encrypt(25)
In [7]:
decrypt(a, b, c)
Out[7]:
महत्वपूर्ण रूप से, ध्यान दें कि यदि हम केवल दो shares के साथ डिक्रिप्ट करने की कोशिश करते हैं, तो डिक्रिप्शन काम नहीं करता है!
In [8]:
decrypt(a, b)
Out[8]:
इस प्रकार, हमें मूल्य को डिक्रिप्ट करने के लिए सभी मालिकों की आवश्यकता है। यह इस तरह से है कि shares
निजी कुंजी की तरह काम करते हैं, जिनमें से सभी को एक मूल्य को डिक्रिप्ट करने के लिए मौजूद होना चाहिए।
In [9]:
x = encrypt(25)
y = encrypt(5)
In [10]:
def add(x, y):
z = list()
# the first worker adds their shares together
z.append((x[0] + y[0]) % Q)
# the second worker adds their shares together
z.append((x[1] + y[1]) % Q)
# the third worker adds their shares together
z.append((x[2] + y[2]) % Q)
return z
In [11]:
decrypt(*add(x,y))
Out[11]:
आखिर तुमने इसे हासिल कर ही लिया है! यदि प्रत्येक कार्यकर्ता (अलग-अलग) अपने शेयरों को एक साथ जोड़ता है, तो परिणामस्वरूप शेयर सही मूल्य (25 + 5 == 30) के लिए डिक्रिप्ट करेंगे।
जैसा कि यह पता चला है, SMPC प्रोटोकॉल मौजूद हैं जो निम्नलिखित कार्यों के लिए इस एन्क्रिप्टेड संगणना की अनुमति दे सकते हैं:
और इन मूल अंतर्निहित प्राथमिकताओं का उपयोग करके, हम मनमानी गणना कर सकते हैं !!!
अगले भाग में, हम इन ऑपरेशनों को करने के लिए PySyft लाइब्रेरी का उपयोग करना सीखेंगे!
पिछले खंडों में, हमने SMPC के आसपास कुछ बुनियादी अंतर्ज्ञानों को रेखांकित किया है जो काम करने वाले हैं। हालाँकि, व्यवहार में हम अपने एन्क्रिप्टेड कार्यक्रमों को लिखने के दौरान स्वयं ही सभी आदिम संचालन को हाथ से लिखना नहीं चाहते हैं। इस प्रकार, इस खंड में हम PySyft का उपयोग करते हुए एन्क्रिप्टेड संगणना कैसे करें की मूल बातों से गुजरने वाले हैं। विशेष रूप से, हम इस बात पर ध्यान केंद्रित करने जा रहे हैं कि पहले बताई गई 3 प्रधान बातें कैसे करें: जोड़, गुणा और तुलना।
सबसे पहले, हमें कुछ Virtual Workers (वर्चुअल वर्कर्स) बनाने की ज़रूरत है (जो उम्मीद है कि अब आप हमारे पिछले ट्यूटोरियल दिए गए हैं)।
In [12]:
import torch
import syft as sy
hook = sy.TorchHook(torch)
bob = sy.VirtualWorker(hook, id="bob")
alice = sy.VirtualWorker(hook, id="alice")
bill = sy.VirtualWorker(hook, id="bill")
In [13]:
x = torch.tensor([25])
In [14]:
x
Out[14]:
In [15]:
encrypted_x = x.share(bob, alice, bill)
In [16]:
encrypted_x.get()
Out[16]:
In [17]:
bob._objects
Out[17]:
In [18]:
x = torch.tensor([25]).share(bob, alice, bill)
In [19]:
# Bob's share
bobs_share = list(bob._objects.values())[0]
bobs_share
Out[19]:
In [20]:
# Alice's share
alices_share = list(alice._objects.values())[0]
alices_share
Out[20]:
In [21]:
# Bill's share
bills_share = list(bill._objects.values())[0]
bills_share
Out[21]:
और अगर हम चाहते थे, हम पहले से बात की गई वही दृष्टिकोण का उपयोग करके इन मूल्यों को डिक्रिप्ट कर सकते हैं !!!
In [22]:
(bobs_share + alices_share + bills_share)
Out[22]:
जैसा कि आप देख सकते हैं, जब हमने .share()
कहा तो यह केवल 3 शेयरों में मूल्य को विभाजित करता है और प्रत्येक पक्ष को एक शेयर भेजता है!
In [23]:
x = torch.tensor([25]).share(bob,alice)
y = torch.tensor([5]).share(bob,alice)
In [24]:
z = x + y
z.get()
Out[24]:
In [25]:
z = x - y
z.get()
Out[25]:
गुणन के लिए हमें एक अतिरिक्त पार्टी की आवश्यकता होती है जो लगातार यादृच्छिक संख्या उत्पन्न करने के लिए ज़िम्मेदार है (और किसी भी अन्य दलों के साथ मिलीभगत नहीं करता है)। हम इस व्यक्ति को "crypto provider" कहते हैं। सभी गहन उद्देश्यों के लिए, crypto provider सिर्फ एक अतिरिक्त VirtualWorker है, लेकिन यह स्वीकार करना महत्वपूर्ण है कि crypto provider एक "मालिक" नहीं है जिसमें वह / उसके पास खुद के शेयर नहीं हैं, लेकिन जिन पर भरोसा किया जा सकता है कि वह मौजूदा शेयरधारकों में से किसी के साथ साँठ गाँठ नहीं करता है।
In [26]:
crypto_provider = sy.VirtualWorker(hook, id="crypto_provider")
In [27]:
x = torch.tensor([25]).share(bob,alice, crypto_provider=crypto_provider)
y = torch.tensor([5]).share(bob,alice, crypto_provider=crypto_provider)
In [28]:
# multiplication
z = x * y
z.get()
Out[28]:
आप मैट्रिक्स गुणा भी कर सकते हैं
In [29]:
x = torch.tensor([[1, 2],[3,4]]).share(bob,alice, crypto_provider=crypto_provider)
y = torch.tensor([[2, 0],[0,2]]).share(bob,alice, crypto_provider=crypto_provider)
In [30]:
# matrix multiplication
z = x.mm(y)
z.get()
Out[30]:
निजी मूल्यों के बीच निजी तुलना करना भी संभव है। हम यहां SecureNN प्रोटोकॉल पर भरोसा करते हैं, जिसका विवरण यहां पाया जा सकता है। तुलना का परिणाम एक निजी साझा टेंसर भी है।
In [31]:
x = torch.tensor([25]).share(bob,alice, crypto_provider=crypto_provider)
y = torch.tensor([5]).share(bob,alice, crypto_provider=crypto_provider)
In [32]:
z = x > y
z.get()
Out[32]:
In [33]:
z = x <= y
z.get()
Out[33]:
In [34]:
z = x == y
z.get()
Out[34]:
In [35]:
z = x == y + 20
z.get()
Out[35]:
आप अधिकतम संचालन भी कर सकते हैं
In [36]:
x = torch.tensor([2, 3, 4, 1]).share(bob,alice, crypto_provider=crypto_provider)
x.max().get()
Out[36]:
In [37]:
x = torch.tensor([[2, 3], [4, 1]]).share(bob,alice, crypto_provider=crypto_provider)
max_values, max_ids = x.max(dim=0)
max_values.get()
Out[37]:
इस नोटबुक ट्यूटोरियल को पूरा करने पर बधाई! यदि आपने इसका आनंद लिया है और एआई और एअर सप्लाई चेन (डेटा) के विकेन्द्रीकृत स्वामित्व के संरक्षण की ओर आंदोलन में शामिल होना चाहते हैं, तो आप निम्न तरीकों से ऐसा कर सकते हैं!
हमारे समुदाय की मदद करने का सबसे आसान तरीका सिर्फ रिपोज अभिनीत है! यह हमारे द्वारा बनाए जा रहे कूल टूल्स के बारे में जागरूकता बढ़ाने में मदद करता है।
नवीनतम प्रगति पर अद्यतित रहने का सबसे अच्छा तरीका हमारे समुदाय में शामिल होना है! http://slack.openmined.org पर फॉर्म भरकर आप ऐसा कर सकते हैं
हमारे समुदाय में योगदान करने का सबसे अच्छा तरीका एक कोड योगदानकर्ता बनना है! किसी भी समय आप PySyft GitHub जारी करने वाले पृष्ठ पर जा सकते हैं और "Projects" के लिए फ़िल्टर कर सकते हैं। यह आपको सभी शीर्ष स्तर के टिकट दिखाएगा कि आप किन परियोजनाओं में शामिल हो सकते हैं! यदि आप किसी परियोजना में शामिल नहीं होना चाहते हैं, लेकिन आप थोड़ी सी कोडिंग करना चाहते हैं, तो आप "good first issue" के रूप में चिह्नित GitHub मुद्दों की खोज करके अधिक मिनी-प्रोजेक्ट्स की तलाश कर सकते हैं।
यदि आपके पास हमारे कोडबेस में योगदान करने का समय नहीं है, लेकिन फिर भी समर्थन उधार देना चाहते हैं, तो आप हमारे ओपन कलेक्टिव में भी एक बैकर बन सकते हैं। सभी दान हमारी वेब होस्टिंग और अन्य सामुदायिक खर्च जैसे कि हैकाथॉन और मीटअप की ओर जाते हैं!
In [ ]: